﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Linq;

namespace eShop.Domain
{
    public class Repository : IRepository
    {
        private readonly ObjectContext _objectContext;

        public Repository(ObjectContext objectContext)
        {
            _objectContext = objectContext;
        }

        protected ObjectContext ObjectContext
        {
            get { return _objectContext; }
        }

        private static Type GetBaseType(Type type)
        {
            Type baseType = type.BaseType;
            if (baseType != null && baseType != typeof(EntityObject))
            {
                return GetBaseType(type.BaseType);
            }
            return type;
        }

        //TODO: Check Type in methods

        #region IRepository Members

        public bool TryGet<TId, T>(TId key, out T entity)
        {
            object o;

            if (ObjectContext.TryGetObjectByKey(key as EntityKey, out o))
            {
                entity = (T)o;
                return true;
            }

            entity = default(T);
            return false;
        }

        public T Get<T, TId>(TId key)
        {
            return (T)ObjectContext.GetObjectByKey(key as EntityKey);
        }

        public List<T> GetAll<T>()
        {
            ObjectQuery<T> query = ObjectContext.CreateQuery<T>("[" + typeof(T).Name + "]");
            return query.ToList();
        }

        public void Save<T>(T entity)
        {
            if (Equals(entity, default(T)))
            {
                throw new ArgumentNullException("entity");
            }

            if ((entity as EntityObject).EntityState == EntityState.Detached)
            {
                _objectContext.AddObject(GetBaseType(typeof(T)).Name, entity);
            }
            _objectContext.SaveChanges();
        }

        public void Delete<T>(T entity)
        {
            _objectContext.DeleteObject(entity);
            _objectContext.SaveChanges();
        }

        #endregion

    }

}
